package com.itheima.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.itheima.ArticleApi;
import com.itheima.CommonResult;
import com.itheima.dtos.ArticleDto;
import com.itheima.mapper.WmChannelMapper;
import com.itheima.mapper.WmNewsMapper;
import com.itheima.dtos.WmNewsDto;
import com.itheima.pojos.ApArticle;
import com.itheima.pojos.WmChannel;
import com.itheima.pojos.WmNews;
import com.itheima.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private ArticleApi articleApi;

    @Autowired
    private WmChannelMapper wmChannelMapper;

    private String listtoString(List<String> images) {
        if (CollectionUtil.isEmpty(images)) {
            return "";
        }
        return org.apache.commons.lang3.StringUtils.join(images, ",");

    }

    @Override
    public Boolean submitNews(WmNewsDto dto) {
        //判空
        if (StringUtils.isEmpty(dto)) {
            throw new RuntimeException("入参不能为空~！！！");
        }
        //组装字段 dto->pojo
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //处理数据库中有的，但是入参没有的字段（估计是没有给默认值）
        // TODO: 2023/1/3 鉴权还没做，先给临时的值
        wmNews.setUserId(0);
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        //处理数据类型不同的字段
        //把集合类型的images转换成字符串类型
        wmNews.setImages(listtoString(dto.getImages()));
        //判断传进来的type字段是多少，这个决定了自动，单图，多图
        Short type = dto.getType();
        //声明一个集合去接收遍历到的图片地址
        List<String> listImage = new ArrayList<>();
        //布局为自动 -1
        if (type == -1) {
            //提取content中所有的图片
            String content = dto.getContent();

            //将json字符串转换成java集合
            List<Map> maps = JSON.parseArray(content, Map.class);
            //遍历集合
            for (Map map : maps) {
                if (map == null) {
                    continue;
                }
                //提取出type = image这一行里面的value值
                Object type1 = map.get("type");
                if ("image".equals(type1)) {
                    String value = (String) map.get("value");
                    //把遍历到的图片地址存到集合里面
                    listImage.add(value);
                }
            }


            //根据图片数量决定type字段的取值
            int size = listImage.size();
            //size = 0 => type => 无图(0)
            //size = 1 => type => 单图(1)
            //size  => 多图模式(3)

            //提取出来的图片列表,覆盖到数据库中的images字段
            if (size > 1) {
                wmNews.setType((short) 3);
            } else {
                wmNews.setType((short) size);
            }
            //将提取出来的图片列表，覆盖到数据库中的images字段中,保留三张图片，这个其实可以在前端做限制
            wmNews.setImages(listtoString(listImage.subList(0, size < 3 ? size : 3)));
        }
        //提取新闻的id
        Integer id = dto.getId();
        if (id == null) {
            //id为空，新增
            //因为实体类中有设置自动生成雪花id，所以这边可以不用管
            int res = wmNewsMapper.insert(wmNews);
            if (res != 1) {
                throw new RuntimeException("新增新闻失败~！");
            }
            //id不为空，修改
            else {
                int res2 = wmNewsMapper.updateById(wmNews);
                if (res2 != 1) {
                    throw new RuntimeException("修改新闻错误~！");
                }
            }
            //判断发布时间,决定是否立即生成app端文章
            Date publishTime = dto.getPublishTime();
            Date currentTime = new Date();

            //如果发布时间 小于当前时间，那么久立即调用app端 feign接口,同步文章
            if (!publishTime.after(currentTime)) {
                //请求app 端的feign接口
                //封装到下面了
                refreshArticle(wmNews);
            }
            //如果发布时间 大于当前时间，就不管他，交给定时任务去处理

        }


        return true;
    }

    /**
     * 用来实现article服务的feign接口
     *
     * @param wmNews
     */
    public void refreshArticle(WmNews wmNews) {
        //feign接口调用完后，要返回文章id
        //然后把文章id回写到当前的新闻表（articleId字段中）
        //组装一下文章内容
        ArticleDto articleDto = new ArticleDto();
        //把前面传进来的东西复制一份给她
        BeanUtils.copyProperties(wmNews, articleDto);
        //补充一下没有的字段
        //作者
        // TODO: 2023/1/5 等鉴权做完，用当前线程用户id去查用户信息


        //频道
        //通过频道id得到频道名称
        WmChannel wmName = wmChannelMapper.selectById(wmNews.getChannelId());
        //判断一下返回来的是否为空
        if (wmName != null) {
            //如果有名字，那么就写到dto里面
            articleDto.setChannelName(wmName.getName());
        }

        //布局
        // wmNews.type e（无图),1 (单图),3（多图)
        // article.Layout 0（无图),1(单图）,2（多图)
        articleDto.setLayout(wmNews.getType() == 3 ? 2 : wmNews.getType());

        CommonResult Result = articleApi.saveArticle(articleDto);
        //从resule中获取articleId
        if (!Result.getCode().equals(200)) {
            throw new RuntimeException("保存文章失败~！！");
        }
        //如果是200 那就是成功了，解析一下内部数据
        //先把boj类型的data数据转成json字符串，再把json转换成java对象使用
        String jsonString = JSON.toJSONString(Result.getData());
        //json转成java对象,后面这个ApArticle.class是需要转的对象，就是把这一整个数据转换成这个对象
        ApArticle apArticle = JSON.parseObject(jsonString, ApArticle.class);
        //然后就可以获取Article Id了就是文章id
        Long apId = apArticle.getId();
        //最后将文章id回写到wmNews表
        wmNews.setArticleId(apId);
        int update = wmNewsMapper.updateById(wmNews);
        if (update != 1) {
            throw new RuntimeException("回写新闻数据异常~！");
        }

    }

    /**
     * 检查未发布的，和发布时间到了的文章（每次提取一篇）
     * @return
     */
    public WmNews check(){
        //设置分页，只取第一条数据,这玩意得配拦截器
        Page<WmNews>page=new Page<>(1,1);

        LambdaQueryWrapper<WmNews>wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(WmNews::getStatus,1);
        //小于当前时间
        wrapper.ne(WmNews::getPublishTime,new Date());

        Page<WmNews> wmNews = wmNewsMapper.selectPage(page,wrapper);
        //判断一下是否为空，如果为空那么就返回null
        if (wmNews==null||CollectionUtil.isEmpty(wmNews.getRecords())){

            return null;
        }
        //获取第一条数据
       return wmNews.getRecords().get(0);
    }


}
